package com.me.study.concurrent.thread.state;

import com.me.common.util.SleepUtil;

/**
 * 测试线程状态： BLOCKED (on object monitor)：in Object.wait()
 *  被 notifyAll() 唤醒，却没有抢到锁。这种情况的线程 BLOCKED，默认被头插到 `Entry Set` 里
 *
 * @author ME
 * @date 2019年1月14日 下午9:39:39
 */
public class TestBlocked {

    public static void main(String[] args) {
        new Thread(() -> Blocked.m1(), "thread-m1").start();
        new Thread(Blocked::m2, "thread-m2").start();

        new Thread(Blocked::m3, "thread-m3").start();
    }

	/** 包装一下 wait 异常处理 */
    public static void wait(Object obj) {
        try {
            obj.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class Blocked {

        public static synchronized void m1() {
            TestBlocked.wait(Blocked.class);
            while (true) {
                System.out.println(Thread.currentThread().getName());
                SleepUtil.seconds(1);
            }
        }

        public static synchronized void m2() {
            TestBlocked.wait(Blocked.class);
            while (true) {
                System.out.println(Thread.currentThread().getName());
                SleepUtil.seconds(1);
            }
        }

        public static synchronized void m3() {
            SleepUtil.seconds(5);
            Blocked.class.notifyAll();
        }
    }

}
